package cn.quang.search.toolkit.component.items.impl;

import cn.quang.search.toolkit.component.AbstractSearchItem;
import cn.quang.search.toolkit.component.ISearch;
import cn.quang.search.toolkit.component.constants.Constants;
import cn.quang.search.toolkit.enums.DataSourceTypeEnum;
import cn.quang.search.toolkit.enums.SearchOperator;
import cn.quang.search.toolkit.provider.entity.KeyOperatorValue;
import cn.quang.search.toolkit.provider.entity.QuerySlice;
import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 针对es的key,value嵌套形式的查询
 * 如：
 * opp{
 *     "id":"1123"
 *     "loginMainStationCt": [
 *           {
 *             "value": "1",
 *             "key": "180"
 *           },{
 *              "value": "2",
 *              "key": "30"
 *            }
 *      ],
 * }
 * 要查询 loginMainStationCt.key=180 loginMainStationCt.value=1
 * 需要写为select * from crm_channel_opp where
 *             nested( 'loginMainStationCt' , loginMainStationCt.key = 180 and loginMainStationCt.value =1 )
 */
public class KeyValueNestedSearchItem extends AbstractSearchItem {

    private final ISearch key;
    private final List<ISearch> values;

    public KeyValueNestedSearchItem(DataSourceTypeEnum dsType, String col, ISearch key, List<ISearch> values) {
        super(dsType, col, SearchOperator.Equal);
        this.key = key;
        this.values = values;
    }
    @Override
    public QuerySlice getQuerySlice() {
        if(dsType == DataSourceTypeEnum.ES) {
            List<String> keys = new ArrayList<>();
            List<String> operators = new ArrayList<>();
            List<Object> values = new ArrayList<>();

            StringBuilder sqlTemplateBuilder = new StringBuilder();
            sqlTemplateBuilder.append("NESTED('").append(Constants.FIELD).append("', ")
                    .append(Constants.FIELD).append(".");
            keys.add(this.col);
            keys.add(this.col);

            QuerySlice keyQuerySlice = key.getQuerySlice();
            sqlTemplateBuilder.append(keyQuerySlice.getSqlTemplate());
            List<KeyOperatorValue> kovForKeys = keyQuerySlice.getKeyOperatorValues();
            if (CollectionUtils.isNotEmpty(kovForKeys)) {
                for (KeyOperatorValue kovForKey : kovForKeys) {
                    keys.addAll(kovForKey.getKeys());
                    operators.addAll(kovForKey.getOperators());
                    values.addAll(kovForKey.getValues());
                }
            }

            if (CollectionUtils.isNotEmpty(this.values)) {
                sqlTemplateBuilder.append(" AND ");
                for (int i = 0; i < this.values.size(); i++) {
                    ISearch item = this.values.get(i);
                    sqlTemplateBuilder.append(Constants.FIELD).append(".");
                    keys.add(this.col);
                    QuerySlice valueSlice = item.getQuerySlice();
                    sqlTemplateBuilder.append(valueSlice.getSqlTemplate()).append(" ");
                    List<KeyOperatorValue> kovForValues = valueSlice.getKeyOperatorValues();
                    if(CollectionUtils.isNotEmpty(kovForValues)) {
                        for (KeyOperatorValue kovForValue : kovForValues) {
                            keys.addAll(kovForValue.getKeys());
                            operators.addAll(kovForValue.getOperators());
                            values.addAll(kovForValue.getValues());
                        }
                    }
                    if( i < (this.values.size() - 1 )){
                        sqlTemplateBuilder.append(" AND ");
                    }
                }
            }

            sqlTemplateBuilder.append(")");
            return QuerySlice.of(
                    sqlTemplateBuilder.toString(),
                    KeyOperatorValue.of(col, keys, operators, values)
            );
        }
        throw new IllegalArgumentException("不支持的数据源！");
    }
}
